package com.linwen.javase.new8.lambda;

import org.junit.Test;

import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;


/**
 * @author : linwen
 * @date : 下午1:37 2021/9/25
 */

public class IambdaTest {

    /**
     * java中lambda表达式的本质是作为函数式接口的实例
     * 函数式接口：接口中只声明了一个抽象方法，此接口称为函数式接口；
     * 函数式接口声明 可以(非必须)  使用@FunctionalInterface 注解
     * 即 必须是接口的一个函数，接口只能有一个函数
     *
     * 跟js，python的匿名函数不一样
     *
     * */

    @Test
    public void test(){
        // new Runnable(){}  匿名内部类 匿名内部类，顾名思义是匿名的，我们无法知道其名字的。内部类作为一个类，他的名字就是类名。匿名内部类，就是没有类名的内部类。
        // 没有去设计类进行实现接口，继承抽象类。直接去用接口、抽象类实例化对象，同时实现接口、抽象类中的抽象方法。这就是匿名内部类了。
        /**
         * 需要传入一个Runnable类对象，Runnable定义如下：
         * @FunctionalInterface
         * public interface Runnable {
         *  public abstract void run ();
         *}
         * 被@FunctionalInterface注解修饰，是一个函数式接口，且其中只有一个抽象方法需要实现。
         * 因此可以写成匿名内部类的方式。
         * */

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("new thread start");
            }
        }).start();
        /**
         * 改写为lambda表达式的方式。改写规则：
         * 格式为(参数列表)->{方法体}
         * 参数类型可推导的，可省略。
         * 方法体只有一行代码的，方法体{}可省略，同时省略，有return的return也省略。
         * 参数只有一个时，参数列表()括号可省略。
         *
         * */
        new Thread(() -> System.out.println("new lambda thread start")).start();

    }
    @Test
    public void test1(){
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);
            }
        };
        int compare = comparator.compare(12, 43);
        System.out.println(compare);

        System.out.println("----------------------------");
        // lambda表达式
        Comparator<Integer> comparator1 = (o1, o2)-> Integer.compare(o1,o2);
        int compare1 = comparator1.compare(34, 6);
        System.out.println(compare1);
        System.out.println("-----------------------------");
        // 方法引用
        Comparator<Integer> comparator2 = Integer::compare;
        int compare2 = comparator2.compare(23, 98);
        System.out.println(compare2);
    }
    /**
     * java中内置的4大函数式接口
     * 消费型接口  Consume<T> void accept(T t)  返回void，主消费t
     * 供给型接口  Supplier<T> T get()  返回t，主返回
     * 函数型接口  Function<T,R>  R apply(T t)  函数型，输入t，返回r
     * 断定型接口  Predicate<T> boolean test(T t)  返回boolean，消费t
     *
     * */
    @Test
    public void test2(){
        Consumer<String> consumer = str -> System.out.println(str+"被消费了。。。");
        consumer.accept("好看的妹子  ");
        Supplier<Integer> supplier = () -> 2<<3;
        System.out.println(supplier.get());
        Function<Integer,String> function = (int1) -> {
            String str1 = "";
            switch (int1){
                case 1:str1 = "this is one";break;
                case 2:str1 =  "this is two";break;
                default:str1 =  "this big than two";
            };
            return str1;
        };
        String apply = function.apply(1);
        System.out.println(apply);
        Predicate<String> predicate = str -> str.length()>3?true:false;
        System.out.println(predicate.test("hello"));
    }

    @Test
    public void testMyFunctionInterface(){
        int a = 5;
        int b = 10;
        // 匿名内部类实现
        int result = new MyFunctionInterface() {
            @Override
            public int add(int a, int b) {
                return a + b;
            }
        }.add(a, b);
        System.out.println(result);
        // 转换成lambda
        System.out.println(((MyFunctionInterface) (a1, b1) -> a1 + b1).add(a, b));
    }




}
